package demo.controller;

import com.taobao.api.ApiException;
import demo.entity.vo.ActualAttendanceVo;
import demo.entity.vo.YearActualAttendanceVO;
import demo.service.OutputService;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;

import javax.swing.*;
import java.awt.*;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @Author Zhengx
 * @Date 2019/9/23
 * @Description
 */
public class OutputController extends JFrame {

    private final OutputService service;

    public OutputController() {
        this.service = new OutputService();
    }

    private static void setCellGBKValue(Cell cell, String value) {
        cell.setCellType(CellType.STRING);
        cell.setCellValue(value);
    }

    private void setInfantCellTitle(HSSFSheet sheet) {
        HSSFRow row = sheet.createRow(0);
        setCellGBKValue(row.createCell((short) 0), "序号");
        setCellGBKValue(row.createCell((short) 1), "员工姓名");
        setCellGBKValue(row.createCell((short) 2), "是否离职");
        setCellGBKValue(row.createCell((short) 3), "开始时间");
        setCellGBKValue(row.createCell((short) 4), "结束时间");
        setCellGBKValue(row.createCell((short) 5), "标准工时");
        setCellGBKValue(row.createCell((short) 6), "加班时长(钉钉统计)");
        setCellGBKValue(row.createCell((short) 7), "加班时长(修正统计)");
        setCellGBKValue(row.createCell((short) 8), "加班时长(修正统计)");
        setCellGBKValue(row.createCell((short) 9), "加班时长(修正减调休)");
        setCellGBKValue(row.createCell((short) 10), "月标准人天");
        setCellGBKValue(row.createCell((short) 11), "核算有效人天");
        setCellGBKValue(row.createCell((short) 12), "加班系数");
        setCellGBKValue(row.createCell((short) 13), "核算时间");
        setCellGBKValue(row.createCell((short) 14), "核算人");
        setCellGBKValue(row.createCell((short) 15), "员工确认状态(0代表未确认,1代表已确认)");
        setCellGBKValue(row.createCell((short) 16), "病假");
        setCellGBKValue(row.createCell((short) 17), "产假");
        setCellGBKValue(row.createCell((short) 18), "婚假");
        setCellGBKValue(row.createCell((short) 19), "例假");
        setCellGBKValue(row.createCell((short) 20), "哺乳假");
        setCellGBKValue(row.createCell((short) 21), "事假");
        setCellGBKValue(row.createCell((short) 22), "年假");
        setCellGBKValue(row.createCell((short) 23), "丧假");
        setCellGBKValue(row.createCell((short) 24), "已审批请教小时(含各类假期)");
        setCellGBKValue(row.createCell((short) 25), "打卡异常时间段");
    }

    private void setInfantCellYearTitle(HSSFSheet sheet) {
        HSSFRow row = sheet.createRow(0);
        setCellGBKValue(row.createCell((short) 0), "序号");
        setCellGBKValue(row.createCell((short) 1), "员工姓名");
        setCellGBKValue(row.createCell((short) 2), "一月(加)");
        setCellGBKValue(row.createCell((short) 3), "一月(休)");
        setCellGBKValue(row.createCell((short) 4), "二月(加)");
        setCellGBKValue(row.createCell((short) 5), "二月(休)");
        setCellGBKValue(row.createCell((short) 6), "三月(加)");
        setCellGBKValue(row.createCell((short) 7), "三月(休)");
        setCellGBKValue(row.createCell((short) 8), "四月(加)");
        setCellGBKValue(row.createCell((short) 9), "四月(休)");
        setCellGBKValue(row.createCell((short) 10), "五月(加)");
        setCellGBKValue(row.createCell((short) 11), "五月(休)");
        setCellGBKValue(row.createCell((short) 12), "六月(加)");
        setCellGBKValue(row.createCell((short) 13), "六月(休)");
        setCellGBKValue(row.createCell((short) 14), "七月(加)");
        setCellGBKValue(row.createCell((short) 15), "七月(休)");
        setCellGBKValue(row.createCell((short) 16), "八月(加)");
        setCellGBKValue(row.createCell((short) 17), "八月(休)");
        setCellGBKValue(row.createCell((short) 18), "九月(加)");
        setCellGBKValue(row.createCell((short) 19), "九月(休)");
        setCellGBKValue(row.createCell((short) 20), "十月(加)");
        setCellGBKValue(row.createCell((short) 21), "十月(休)");
        setCellGBKValue(row.createCell((short) 22), "十一月(加)");
        setCellGBKValue(row.createCell((short) 23), "十一月(休)");
        setCellGBKValue(row.createCell((short) 24), "十二月(加)");
        setCellGBKValue(row.createCell((short) 25), "十二月(休)");
    }

    private void createRSExcel(List<ActualAttendanceVo> actualAttendanceVos, List<YearActualAttendanceVO> years, boolean monthOrYear) throws Exception {

        HSSFWorkbook workBook = new HSSFWorkbook();
        try {
            HSSFSheet sheet = workBook.createSheet("sheel1");
            if (monthOrYear) {
                setInfantCellTitle(sheet);
                for (int i = 1; i < actualAttendanceVos.size(); i++) {
                    HSSFRow row = sheet.createRow(i);
                    ActualAttendanceVo actualAttendanceVo = actualAttendanceVos.get(i);
                    Class cls = actualAttendanceVo.getClass();
                    Field[] fields = cls.getDeclaredFields();
                    for (int j = 0; j < fields.length; j++) {
                        Field f = fields[j];
                        f.setAccessible(true);
                        row.createCell((short) j).setCellValue(null == f.get(actualAttendanceVo) ? "" : String.valueOf(f.get(actualAttendanceVo)));
                    }
                }
            } else {
                setInfantCellYearTitle(sheet);
                for (int i = 1; i < years.size(); i++) {
                    HSSFRow row = sheet.createRow(i);
                    YearActualAttendanceVO yearActualAttendanceVO = years.get(i);
                    Class cls = yearActualAttendanceVO.getClass();
                    Field[] fields = cls.getDeclaredFields();
                    for (int j = 0; j < fields.length; j++) {
                        Field f = fields[j];
                        f.setAccessible(true);
                        row.createCell((short) j).setCellValue(null == f.get(yearActualAttendanceVO) ? "" : String.valueOf(f.get(yearActualAttendanceVO)));
                    }
                }
            }

            FileDialog fd = new FileDialog(this, "导出考勤加班结果集", FileDialog.SAVE);
            fd.setLocation(500, 350);
            fd.setVisible(true);
            String stringFile = fd.getDirectory() + fd.getFile() + ".xls";

            FileOutputStream fOut = new FileOutputStream(stringFile);
            workBook.write(fOut);
            fOut.flush();
            fOut.close();
            JOptionPane.showMessageDialog(null, "导出成功！");
        } catch (java.io.FileNotFoundException ex) {
            JOptionPane.showMessageDialog(null,
                    "所要导出的Excel文件被占用，请关闭该文件并重试此操作！");
        }
    }


    public void outputExcel(int month, String workdays, String restWorkdays, String days) throws Exception {
        int day = Integer.parseInt(days);
        List<ActualAttendanceVo> actualAttendanceVos = service.getActualAttendanceVos(month, workdays, restWorkdays);
        actualAttendanceVos = actualAttendanceVos.stream().peek(a -> {
            a.setStandardDays(new BigDecimal(day));
            a.setValidDays(a.getStandardDays().add(a.getActualOvertime().divide(new BigDecimal(8), 2, BigDecimal.ROUND_HALF_UP)));
        }).collect(Collectors.toList());
        createRSExcel(actualAttendanceVos, null, true);
    }


    public void outputYearOvertimeExcel() throws Exception {
        List<YearActualAttendanceVO> actualAttendanceVos = service.getYearActualAttendanceVos();
        createRSExcel(null, actualAttendanceVos, false);
    }

    public void users() throws ApiException {
        service.test();
    }
}
